﻿
Imports std
Imports storoomc
Imports elpmis

Namespace storoomFunctions
    Public Class struct
        Inherits storoomc.struct

        Protected Overrides Function enableModify() As Boolean
            Return True
        End Function

        Protected Overrides Function enableRead() As Boolean
            Return True
        End Function

        Protected Overrides Function enableUniqueWrite() As Boolean
            Return True
        End Function

        Protected Overrides Function enableWrite() As Boolean
            Return True
        End Function

        Protected Overrides Function keyprefix() As String
            Return Nothing
        End Function
    End Class

    Friend Module storoomshare
        Friend Function matchstruct(ByVal i As bare_variable) As Boolean
            Return Not i Is Nothing AndAlso i.variable().isType(typeDefination.var) AndAlso _
                   Not i.value() Is Nothing AndAlso istype(Of pointer(Of struct), Object)(i.value())
        End Function

        Friend Enum modeselector
            write = 0
            modify
            uniqueWrite
        End Enum

        Friend Function modeselect(ByVal i As bare_variable) As modeselector
            If i Is Nothing OrElse i.value() Is Nothing Then
                Return modeselector.write
            Else
                If i.variable().isType(typeDefination.int, False) Then
                    Return Convert.ToInt64(i.value())
                ElseIf i.variable().isType(typeDefination.var, False) Then
                    Dim mode As Int64
                    If convertor.toint64(i.value(), mode) Then
                        Return mode
                    Else
                        Return modeselector.write
                    End If
                Else
                    Dim m As String = Nothing
                    m = Convert.ToString(i.value())
                    If strsame(m, "modify", False) Then
                        Return modeselector.modify
                    ElseIf strsame(m, "uniqueWrite", False) Then
                        Return modeselector.uniqueWrite
                    Else
                        Return modeselector.write
                    End If
                End If
            End If
        End Function
    End Module

    Public Class storoomhealth
        Inherits noInputFunction(Of Boolean)

        Public Sub New()
            MyBase.new("storoom.health")
        End Sub

        Protected Overrides Function invoke(ByRef o As Boolean) As Boolean
            o = storoom.health()
            Return True
        End Function

        Protected Overrides Function returnType() As typeDefination
            Return typeDefination.bool
        End Function
    End Class

    'parameters, NA
    'return, var, a pointer of struct, map is cloneable, so uses pointer<struct>, can use std.* to operate
    Public Class storoomstructcreator
        Inherits internalFunction

        Public Class parameters
        End Class

        Public Sub New()
            MyBase.New("storoom.struct.create")
        End Sub

        Protected Overrides Function invoke(ByVal ctx As context, ByRef output As bare_variable) As Boolean
            output = New bare_variable(typeDefination.var, New pointer(Of struct)(New struct))
            Return True
        End Function
    End Class

    'parameters, key, any, convert to string
    '            struct, var, a pointer of struct, for the read operation
    'return, bool, whether the read is success or not
    Public Class storoomstructread
        Inherits internalFunction

        Public Class parameters
            Public Const key As String = "key"
            Public Const struct As String = "struct"
        End Class

        Private Shared m As iParametersMapping = Nothing

        Shared Sub New()
            initialMapping(m, parameters.key, parameters.struct)
        End Sub

        Public Sub New()
            MyBase.New("storoom.struct.read", m)
        End Sub

        Protected Overrides Function invoke(ByVal ctx As context, ByRef output As bare_variable) As Boolean
            Dim key As bare_variable = Nothing
            key = ctx.findVariable(parameters.key)
            If key Is Nothing Then
                raiseError("expect parameter " + parameters.key, errorHandle.errorType.user)
                Return False
            Else
                Dim structv As bare_variable = Nothing
                structv = ctx.findVariable(parameters.struct)
                If Not matchstruct(structv) Then
                    raiseError("expect parameter " + parameters.struct + _
                               " is a struct object created by storoom.struct.create.", errorHandle.errorType.user)
                    Return False
                Else
                    Dim s As struct = Nothing
                    s = +(convertor.cast(Of pointer(Of struct))(structv.value()))
                    If s.read(Convert.ToString(key.value())) Then
                        output = New bare_variable(typeDefination.bool, True)
                    Else
                        output = New bare_variable(typeDefination.bool, False)
                    End If
                    Return True
                End If
            End If
        End Function
    End Class

    'parameters, key, any, convert to string
    '            struct, var, a pointer of struct
    '            mode, int, 0 - write, 1 - modify, 2 - uniqueWrite
    '                  any, convert to string, write, modify, uniqueWrite
    '                  default value is write
    'return, bool, whether write/modify/uniqueWrite is success or not
    Public Class storoomstructwrite
        Inherits internalFunction

        Public Class parameters
            Public Const key As String = "key"
            Public Const struct As String = "struct"
            Public Const mode As String = "mode"
        End Class

        Private Shared m As iParametersMapping = Nothing

        Shared Sub New()
            initialMapping(m, parameters.key, parameters.struct, parameters.mode)
        End Sub

        Public Sub New()
            MyBase.New("storoom.struct.write", m)
        End Sub

        Protected Overrides Function invoke(ByVal ctx As context, ByRef output As bare_variable) As Boolean
            Dim keyv As bare_variable = Nothing
            keyv = ctx.findVariable(parameters.key)
            If keyv Is Nothing Then
                raiseError("expect parameter " + parameters.key, errorHandle.errorType.user)
                Return False
            Else
                Dim structv As bare_variable = Nothing
                structv = ctx.findVariable(parameters.struct)
                If Not matchstruct(structv) Then
                    raiseError("expect parameter " + parameters.struct + " is struct.", errorHandle.errorType.user)
                    Return False
                Else
                    Dim mode As modeselector
                    mode = modeselect(ctx.findVariable(parameters.mode))
                    Dim s As struct = Nothing
                    s = +(convertor.cast(Of pointer(Of struct))(structv))
                    Dim key As String = Nothing
                    key = Convert.ToString(keyv.value())
                    Dim rtn As Boolean
                    Select Case mode
                        Case modeselector.modify
                            rtn = s.modify(key)
                        Case modeselector.uniqueWrite
                            rtn = s.uniqueWrite(key)
                        Case Else
                            rtn = s.write(key)
                    End Select

                    output = New bare_variable(typeDefination.bool, rtn)
                    Return True
                End If
            End If
        End Function
    End Class

    'parameters, s, std.set<string>, the output
    '            v, std.vector<string>, the output, use one of them
    'return, bool, whether the operation is success or not
    Public Class storoomlist
        Inherits internalFunction

        Public Class parameters
            Public Const s As String = "s"
            Public Const v As String = "v"
        End Class

        Private Shared m As iParametersMapping = Nothing

        Shared Sub New()
            initialMapping(m, parameters.v)
        End Sub

        Public Sub New()
            MyBase.New("storoom.list", m)
        End Sub

        Private Shared Function matchtemplatestr(ByVal i As bare_variable, ByVal t As typeDefination) As Boolean
            Return Not i Is Nothing AndAlso Not i.value() Is Nothing AndAlso _
                   i.variable().isType(t) AndAlso i.variable().elementType1() = typeDefination.string
        End Function

        Private Shared Function matchsetstr(ByVal i As bare_variable) As Boolean
            Return matchtemplatestr(i, typeDefination.set)
        End Function

        Private Shared Function matchvectorstr(ByVal i As bare_variable) As Boolean
            Return matchtemplatestr(i, typeDefination.vector)
        End Function

        Protected Overrides Function invoke(ByVal ctx As context, ByRef output As bare_variable) As Boolean
            Dim s As [set](Of String) = Nothing
            Dim v As vector(Of String) = Nothing
            Dim sv As bare_variable = Nothing
            sv = ctx.findVariable(parameters.s)
            If Not matchsetstr(sv) Then
                Dim vv As bare_variable = Nothing
                vv = ctx.findVariable(parameters.v)
                If Not matchvectorstr(vv) Then
                    raiseError("expect parameter " + parameters.s + ", or " + parameters.v, errorHandle.errorType.user)
                    Return False
                Else
                    v = +(convertor.cast(Of pointer(Of vector(Of String)))(vv.value()))
                End If
            Else
                s = +(convertor.cast(Of pointer(Of [set](Of String)))(sv.value()))
            End If

            Dim rtn As Boolean
            If Not s Is Nothing Then
                rtn = storoom.list(s)
            ElseIf Not v Is Nothing Then
                rtn = storoom.list(v)
            Else
                assert(False, "should not go here without both s and v.")
            End If

            output = New bare_variable(typeDefination.bool, rtn)
            Return True
        End Function
    End Class

    'parameters, host, any, convert to string, the host name / ip of destination storoom
    '            port, int, the port
    'return, bool, whether success or not
    Public Class storoomsettalk
        Inherits internalFunction

        Public Class parameters
            Public Const host As String = "host"
            Public Const port As String = "port"
        End Class

        Private Shared m As iParametersMapping = Nothing

        Shared Sub New()
            initialMapping(m, parameters.host, parameters.port)
        End Sub

        Public Sub New()
            MyBase.New("storoom.settalk", m)
        End Sub

        Protected Overrides Function invoke(ByVal ctx As context, ByRef output As bare_variable) As Boolean
            Dim hostv As bare_variable = Nothing
            hostv = ctx.findVariable(parameters.host)
            If hostv Is Nothing Then
                raiseError("expect parameter " + parameters.host, errorHandle.errorType.user)
                Return False
            Else
                Dim portv As bare_variable = Nothing
                portv = ctx.findVariable(parameters.port)
                If portv Is Nothing OrElse portv.value() Is Nothing OrElse Not _
                   portv.variable().isType(typeDefination.int, True) Then
                    raiseError("expect parameter " + parameters.port + " is int.", errorHandle.errorType.user)
                    Return False
                Else
                    Dim host As String = Nothing
                    host = Convert.ToString(hostv.value())
                    Dim port As Int32
                    If Not convertor.toint32(portv.value(), port) Then
                        raiseError("cannot convert parameter " + parameters.port + " to int/int32.", _
                                   errorHandle.errorType.user)
                        Return False
                    End If

                    storoom = storoomTalks.get(host, port)
                    output = New bare_variable(typeDefination.bool, True)
                    Return True
                End If
            End If
        End Function
    End Class

    'parameters, key, any, convert to string
    '            i, pointer<string>, for output
    'return, bool, whether the read is success or not
    Public Class storoomread
        Inherits internalFunction

        Public Class parameters
            Public Const key As String = "key"
            Public Const i As String = "i"
        End Class

        Private Shared m As iParametersMapping = Nothing

        Shared Sub New()
            initialMapping(m, parameters.key, parameters.i)
        End Sub

        Public Sub New()
            MyBase.New("storoom.read", m)
        End Sub

        Protected Overrides Function invoke(ByVal ctx As elpmis.context, ByRef output As bare_variable) As Boolean
            Dim key As bare_variable = Nothing
            key = ctx.findVariable(parameters.key)
            If key Is Nothing Then
                raiseError("expect parameter " + parameters.key, errorHandle.errorType.user)
                Return False
            Else
                Dim i As bare_variable = Nothing
                i = ctx.findVariable(parameters.i)
                If i Is Nothing Then
                    raiseError("expect parameter " + parameters.i, errorHandle.errorType.user)
                    Return False
                ElseIf Not i.variable().isPointerOfString() Then
                    raiseError("expect parameter " + parameters.i + " is pointer<string>/pointer<var>.", _
                               errorHandle.errorType.user)
                    Return False
                Else
                    Dim buff As bytes = Nothing
                    If storoom.read(Convert.ToString(key.value()), buff) AndAlso _
                       i.setPointerOfString(encoding.utf8().GetString(buff)) Then
                        output = New bare_variable(typeDefination.bool, True)
                    Else
                        output = New bare_variable(typeDefination.bool, False)
                    End If

                    Return True
                End If
            End If
        End Function
    End Class

    'parameters, key, any, convert to string
    '            value, any, convert to string, and utf8 bytes
    '            mode, same as storoomstructwrite
    'return, bool, whether the operation is success or not
    Public Class storoomwrite
        Inherits internalFunction

        Public Class parameters
            Public Const key As String = "key"
            Public Const o As String = "o"
            Public Const mode As String = "mode"
        End Class

        Private Shared m As iParametersMapping = Nothing

        Shared Sub New()
            initialMapping(m, parameters.key, parameters.o, parameters.mode)
        End Sub

        Public Sub New()
            MyBase.New("storoom.write", m)
        End Sub

        Protected Overrides Function invoke(ByVal ctx As context, ByRef output As bare_variable) As Boolean
            Dim key As bare_variable = Nothing
            key = ctx.findVariable(parameters.key)
            If key Is Nothing Then
                raiseError("expect parameter " + parameters.key, errorHandle.errorType.user)
                Return False
            Else
                Dim o As bare_variable = Nothing
                o = ctx.findVariable(parameters.o)
                If o Is Nothing Then
                    raiseError("expect parameter " + parameters.o, errorHandle.errorType.user)
                    Return False
                Else
                    Dim mode As modeselector
                    mode = modeselect(ctx.findVariable(parameters.mode))
                    Dim rtn As Boolean
                    Dim key2 As String = Nothing
                    key2 = Convert.ToString(key.value())
                    Dim buff As bytes = Nothing
                    buff = encoding.utf8().GetBytes(Convert.ToString(o.value()))
                    Select Case mode
                        Case modeselector.modify
                            rtn = storoom.modify(key2, buff)
                        Case modeselector.uniqueWrite
                            rtn = storoom.uniqueWrite(key2, buff)
                        Case Else
                            rtn = storoom.write(key2, buff)
                    End Select
                    output = New bare_variable(typeDefination.bool, rtn)
                    Return True
                End If
            End If
        End Function
    End Class

    Public Class storoomsizeof
        Inherits inputIOutputOFunction(Of String, Int64)

        Public Sub New()
            MyBase.New("storoom.sizeof")
        End Sub

        Protected Overrides Function finder() As iVariableFinder(Of String)
            Return string_finder()
        End Function

        Protected Overrides Function invoke(ByVal i As String, ByRef o As Int64) As Boolean
            Return storoom.sizeof(i, o)
        End Function

        Protected Overrides Function outputType() As typeDefination
            Return typeDefination.int
        End Function
    End Class

    Public Class storoomwritefile
        Inherits internalFunction

        Private Class parameters
            Public Const directory As String = "directory"
            Public Const filename As String = "filename"
            Public Const localfile As String = "localfile"
        End Class

        Private Shared m As iParametersMapping = Nothing

        Shared Sub New()
            initialMapping(m, parameters.directory, parameters.filename, parameters.localfile)
        End Sub

        Public Sub New()
            MyBase.New("storoom.directorystore.write", m)
        End Sub

        Protected Overrides Function invoke(ByVal ctx As context, ByRef output As bare_variable) As Boolean
            Dim directory As String = Nothing
            Dim filename As String = Nothing
            Dim localfile As String = Nothing
            directory = ctx.findVariableStr(parameters.directory)
            filename = ctx.findVariableStr(parameters.filename)
            localfile = ctx.findVariableStr(parameters.localfile)
            Dim buff As bytes = Nothing
            output = New bare_variable(typeDefination.bool, _
                                       readfile(localfile, buff) AndAlso _
                                       directorystore.writefile(directory, filename, buff))
            Return True
        End Function
    End Class

    Public Class storoomreadfile
        Inherits internalFunction

        Private Class parameters
            Public Const directory As String = "directory"
            Public Const filename As String = "filename"
            Public Const buff As String = "buff"
        End Class

        Private Shared m As iParametersMapping = Nothing

        Shared Sub New()
            initialMapping(m, parameters.directory, parameters.filename, parameters.buff)
        End Sub

        Public Sub New()
            MyBase.new("storoom.directorystore.read", m)
        End Sub

        Protected Overrides Function invoke(ByVal ctx As context, ByRef output As bare_variable) As Boolean
            Dim directory As String = Nothing
            Dim filename As String = Nothing
            Dim buff As bare_variable = Nothing
            directory = ctx.findVariableStr(parameters.directory)
            filename = ctx.findVariableStr(parameters.filename)
            buff = ctx.findVariable(parameters.buff)
            If buff Is Nothing Then
                raiseError(errorHandle.errorType.user, "expect parameter ", parameters.buff)
                Return False
            ElseIf Not buff.variable().isPointerOfVar() Then
                raiseError(errorHandle.errorType.user, "expect parameter ", parameters.buff, " is pointer<var>.")
                Return False
            Else
                Dim bt As bytes = Nothing
                output = New bare_variable(typeDefination.bool, _
                                           directorystore.readfile(directory, filename, bt) AndAlso _
                                           buff.setPointerOfVar(bt))
                Return True
            End If
        End Function
    End Class

    Public Class storoomlistfile
        Inherits inputIFunction(Of String, elpmis_vector(Of String))

        Public Sub New()
            MyBase.new("storoom.directorystore.list")
        End Sub

        Protected Overrides Function finder() As iVariableFinder(Of String)
            Return string_finder()
        End Function

        Protected Overrides Function returnType() As typeDefination
            Return typeDefination.vector
        End Function

        Protected Overrides Function elementType1() As typeDefination
            Return typeDefination.string
        End Function

        Protected Overrides Function invoke(ByVal i As String, ByRef o As elpmis_vector(Of String)) As Boolean
            Dim rtn As vector(Of String) = Nothing
            If Not directorystore.listfiles(i, rtn) Then
                rtn = New vector(Of String)()
            End If

            o = New elpmis_vector(Of String)(rtn)
            Return True
        End Function
    End Class

    Public Class storoomexistfile
        Inherits internalFunction

        Private Class parameters
            Public Const directory As String = "directory"
            Public Const filename As String = "filename"
        End Class

        Private Shared m As iParametersMapping = Nothing

        Shared Sub New()
            initialMapping(m, parameters.directory, parameters.filename)
        End Sub

        Public Sub New()
            MyBase.New("storoom.directorystore.exist", m)
        End Sub

        Protected Overrides Function invoke(ByVal ctx As context, ByRef output As bare_variable) As Boolean
            Dim directory As String = Nothing
            Dim filename As String = Nothing
            directory = ctx.findVariableStr(parameters.directory)
            filename = ctx.findVariableStr(parameters.filename)
            output = New bare_variable(typeDefination.bool, directorystore.existfile(directory, filename))
            Return True
        End Function
    End Class

    Public Class storoomsizeoffile
        Inherits internalFunction

        Private Class parameters
            Public Const directory As String = "directory"
            Public Const filename As String = "filename"
            Public Const output As String = "output"
        End Class

        Private Shared m As iParametersMapping = Nothing

        Shared Sub New()
            initialMapping(m, parameters.directory, parameters.filename, parameters.output)
        End Sub

        Public Sub New()
            MyBase.new("storoom.directorystore.sizeof", m)
        End Sub

        Protected Overrides Function invoke(ByVal ctx As context, ByRef output As bare_variable) As Boolean
            Dim directory As String = Nothing
            Dim filename As String = Nothing
            Dim o As bare_variable = Nothing
            directory = ctx.findVariableStr(parameters.directory)
            filename = ctx.findVariableStr(parameters.filename)
            If Not ctx.findVariable(parameters.output, o) Then
                raiseError(errorHandle.errorType.user, "expect parameter ", parameters.output)
                Return False
            ElseIf Not o.variable().isPointerOf(typeDefination.int) Then
                raiseError(errorHandle.errorType.user, _
                           "expect parameter ", parameters.output, " is pointer<int> or pointer<var>")
                Return False
            Else
                Dim i As UInt64 = 0
                output = New bare_variable(typeDefination.bool, _
                                           directorystore.sizeoffile(directory, filename, i) AndAlso _
                                           o.setPointerOfInt(i))
                Return True
            End If
        End Function
    End Class
End Namespace
